home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Graphics 2D / CollectPictColors / CLUTBuilder.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  8.8 KB  |  316 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        CLUTBuilder.c
  3.  
  4.     Contains:    this file contains functions used to pull colors from a PICT.  You activate it by
  5.                 calling CollectColors(PicHandle) with PicHandle set to a PICT that you have already
  6.                 loaded into memory.  It will almost invariably return a (handle to a) color table
  7.                 (that contains at least black and white) however the color table is not at all clean
  8.                 in the current implementation.  It is probably ok if you run it through NewPalette.
  9.                 If it runs across a direct pixmap it won't bomb but it won't add any colors to the
  10.                 color table.
  11.     
  12.                 WARNING: This code has been tested but it has not been tested thoroughly;
  13.                 USE AT YOUR OWN RISK!
  14.  
  15.     Written by: Jon Zap    
  16.  
  17.     Copyright:    Copyright © 1989-1999 by Apple Computer, Inc., All Rights Reserved.
  18.  
  19.                 You may incorporate this Apple sample source code into your program(s) without
  20.                 restriction. This Apple sample source code has been provided "AS IS" and the
  21.                 responsibility for its operation is yours. You are not permitted to redistribute
  22.                 this Apple sample source code as "Apple sample source code" after having made
  23.                 changes. If you're going to re-distribute the source, we require that you make
  24.                 it clear in the source that the code was descended from Apple sample source
  25.                 code, but that you've made changes.
  26.  
  27.     Change History (most recent first):
  28.                 7/8/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  29.                 
  30.  
  31. */
  32. #include "CLUTBuilder.h"
  33. #define    applec
  34.  
  35.  
  36. /* Add a color to the color table. */
  37. void AddRGBColor(RGBColor * rgb)
  38. {
  39.     long numSpecs,sizeInBytes;
  40.     int     i,ctSize;
  41.     CTabPtr TablePtr;
  42.     RGBColor rgbx;
  43.     
  44.     if (gColorError)
  45.         return;
  46.     
  47.     TablePtr = (*gColorTable);
  48.     ctSize = TablePtr -> ctSize;
  49.     for (i = 0; i <= ctSize; i++) {
  50.         rgbx = TablePtr->ctTable[i].rgb;
  51.         if (rgbx.red==(*rgb).red &&
  52.             rgbx.green==(*rgb).green &&
  53.             rgbx.blue==(*rgb).blue) 
  54.             return;        /* if already there, done */
  55.     }
  56.     numSpecs = (long) (++(**gColorTable).ctSize);    /* add a colorspec to table */
  57.     sizeInBytes = (numSpecs * sizeof(ColorSpec)) + sizeof(ColorTable);
  58.     SetHandleSize((Handle)gColorTable, sizeInBytes);
  59.     if ((gColorError = MemError()) == noErr) {
  60.         (**gColorTable).ctTable[numSpecs].rgb = *rgb;
  61.         (**gColorTable).ctTable[numSpecs].value = 0;
  62.     }
  63. }
  64.  
  65. /* Add the contents of another color table to our color table.*/
  66. void AddColorTable(CTabHandle cTab)
  67. {
  68.     short index,size;
  69.     RGBColor color;
  70.     size = (**cTab).ctSize;
  71.     for (index= 0; index <= size; index++) {
  72.         color = (**cTab).ctTable[index].rgb;
  73.         AddRGBColor(&color);
  74.     }
  75. }
  76.  
  77. /* Add the foreground color of the current port to the color table. */
  78. void AddRGBForeColor()
  79. {
  80. #ifdef applec
  81.     AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbFgColor));
  82. #else
  83.     AddRGBColor(&((*(CGrafPtr)thePort).rgbFgColor));
  84. #endif
  85. }
  86.  
  87. /* Add the background color of the current port to the color table. */
  88. void AddRGBBackColor()
  89. {
  90. #ifdef applec
  91.     AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbBkColor));
  92. #else
  93.     AddRGBColor(&((*(CGrafPtr)thePort).rgbBkColor));
  94. #endif
  95. }
  96.  
  97. /* Add colors from a PixPat to a color table. */
  98. void AddPixPat(PixPatHandle pPat)
  99. {
  100.     switch ((**pPat).patType) {
  101.     
  102.     case 0:        /* one-bit patterns are drawn in the foreground and background color. */
  103.         AddRGBForeColor();
  104.         AddRGBBackColor();
  105.         break;
  106.     case 1:        /* Type 1 PixPats have a color table. */
  107.         AddColorTable((**(**pPat).patMap).pmTable);
  108.         break;
  109.     }
  110. }
  111.  
  112. /* Add colors from the pen PixPat to the color table. */
  113. void AddPenPixPat()
  114. {
  115. #ifdef applec
  116.     AddPixPat((*(CGrafPtr)qd.thePort).pnPixPat);
  117. #else
  118.     AddPixPat((*(CGrafPtr)thePort).pnPixPat);
  119. #endif
  120. }
  121.  
  122. /* Add colors from the fill PixPat to the color table. */
  123. void AddFillPixPat()
  124. {
  125. #ifdef applec
  126.     AddPixPat((*(CGrafPtr)qd.thePort).fillPixPat);
  127. #else
  128.     AddPixPat((*(CGrafPtr)thePort).fillPixPat);
  129. #endif
  130. }
  131.  
  132. /* Add colors because we are about to draw an object. */
  133. void AddVerb(GrafVerb verb)
  134. {
  135.     switch (verb) {
  136.     
  137.     case kQDGrafVerbFrame:
  138.     case kQDGrafVerbPaint: /* Framed and painted objects are drawn in the pen PixPat. */
  139.             AddPenPixPat();
  140.             break;
  141.     case kQDGrafVerbErase: /* Erased objects are drawn in the background color. */
  142.             AddRGBBackColor();
  143.             break;
  144.     case kQDGrafVerbFill:
  145.             /* Filled objects are drawn in the fill PixPat.  The fillPixPat is
  146.                 a pattern used to record fill commands for pictures.  First, a
  147.                 command to set the fillPixPat is recorded, then the fill command
  148.                 is recorded. */
  149.             AddFillPixPat();
  150.     }
  151. }
  152.  
  153. /* bottleneck routines follow . . . */
  154.  
  155. pascal void ColorTextProc(short byteCount, Ptr textBuf, Point numer, Point denom)
  156. {    /* Text is drawn with the foreground and background colors.*/
  157. #ifdef applec
  158. #pragma unused (byteCount, textBuf, numer, denom)
  159. #endif
  160.     AddRGBForeColor();
  161.     AddRGBBackColor();
  162. }
  163.  
  164. pascal void ColorLineProc(Point newPt)
  165. { /* Lines are drawn with the pen PixPat. */
  166. #ifdef applec
  167. #pragma unused (newPt)
  168. #endif
  169.     AddPenPixPat();
  170. }
  171.  
  172. pascal void ColorRectProc(GrafVerb verb,Rect* r)
  173. {
  174. #ifdef applec
  175. #pragma unused (r)
  176. #endif
  177.     AddVerb(verb);
  178. }
  179.  
  180. pascal void ColorRRectProc(GrafVerb verb,Rect* r, short ovalWidth,short ovalHeight)
  181. {
  182. #ifdef applec
  183. #pragma unused (r, ovalWidth, ovalHeight)
  184. #endif
  185.     AddVerb(verb);
  186. }
  187.  
  188. pascal void ColorOvalProc(GrafVerb verb,Rect r)
  189. {
  190. #ifdef applec
  191. #pragma unused (r)
  192. #endif
  193.     AddVerb(verb);
  194. }
  195.  
  196. pascal void ColorArcProc(GrafVerb verb,Rect* r,short startAngle,short arcAngle)
  197. {
  198. #ifdef applec
  199. #pragma unused (r, startAngle, arcAngle)
  200. #endif
  201.     AddVerb(verb);
  202. }
  203.  
  204. pascal void ColorPolyProc(GrafVerb verb, PolyHandle poly)
  205. {
  206. #ifdef applec
  207. #pragma unused (poly)
  208. #endif
  209.     AddVerb(verb);
  210. }
  211.  
  212. pascal void ColorRgnProc(GrafVerb verb,RgnHandle rgn)
  213. {
  214. #ifdef applec
  215. #pragma unused (rgn)
  216. #endif
  217.     AddVerb(verb);
  218. }
  219.  
  220. pascal void ColorBitsProc(BitMap* BitsPtr,Rect srcRect, Rect dstRect,short mode,RgnHandle maskRgn)
  221. {
  222. #ifdef applec
  223. #pragma unused (srcRect, dstRect, mode, maskRgn)
  224. #endif
  225.     PixMapPtr aPixMap;
  226.     short tempRB;
  227.  
  228.     /* Get the PixMap that we are about to draw.  SrcBits might be a BitMap, or
  229.         one of two different kinds of PixMap pointers.  */
  230.     tempRB = BitsPtr->rowBytes;            /* local copy of rowBytes */
  231.     if (tempRB < 0) {                        /* high bit set? */
  232.         if ((tempRB<<1) < 0)                /* next to high bit set? */
  233.             aPixMap = (PixMapPtr)BitsPtr;    /* ptr to PixMap handle */
  234.         else
  235.             aPixMap = (PixMapPtr) BitsPtr;        /* pointer to a PixMap */
  236.         if ((*aPixMap).pixelSize > maxPixDepth)    /* deepest pixmap so far? */
  237.             maxPixDepth = (*aPixMap).pixelSize;
  238.         if ((*aPixMap).pixelType==16) {
  239.             foundDirect = true;
  240.             return;                                /* direct pixmap?  eek! */
  241.         }
  242.         AddColorTable((*aPixMap).pmTable);        /* it has its own color table. */
  243.     }
  244.     else {
  245.         /* It's just a BitMap; it will use the background and foreground colors. */
  246.         AddRGBBackColor();
  247.         AddRGBForeColor();
  248.     }
  249. }
  250.  
  251. RGBColor whiteRGB = { 0xFFFF,0xFFFF,0xFFFF };
  252. RGBColor blackRGB = { 0,0,0 };
  253.  
  254. CTabHandle CollectColors(PicHandle fromPicture,short * depthPtr,short * directFlagPtr)
  255. {
  256.     CTabHandle colors;
  257.     CQDProcs bottlenecks;
  258.  
  259.     /* Set the bottlenecks.  These bottlenecks will figure out what colors are in
  260.         a picture, but won't draw anything.
  261.     Note: the bottlenecks are installed in thePort, which must be a color port.
  262.     */
  263.     SetStdCProcs(&bottlenecks);
  264.     bottlenecks.textProc = NewQDTextProc(ColorTextProc);
  265.     bottlenecks.lineProc = NewQDLineProc(ColorLineProc);
  266.     bottlenecks.rectProc = NewQDRectProc(ColorRectProc);
  267.     bottlenecks.rRectProc = NewQDRRectProc(ColorRRectProc);
  268.     bottlenecks.ovalProc = NewQDOvalProc(ColorOvalProc);
  269.     bottlenecks.arcProc = NewQDArcProc(ColorArcProc);
  270.     bottlenecks.polyProc = NewQDPolyProc(ColorPolyProc);
  271.     bottlenecks.rgnProc = NewQDRgnProc(ColorRgnProc);
  272.     bottlenecks.bitsProc =NewQDBitsProc(ColorBitsProc);
  273.  
  274.     /* Create a color table containing black and white. */
  275.     foundDirect = false;    /* haven't found a direct pixmap yet */
  276.     maxPixDepth = 1;        /* assume we will find a bitmap */
  277.     colors = (CTabHandle) NewHandle( sizeof(ColorTable) + sizeof(ColorSpec) );
  278.     if (colors) {
  279.         (**colors).ctSize = 1; /* 2 entries */
  280. #ifdef applec
  281.         (**colors).ctFlags = 0x8000;
  282. #else
  283.         (**colors).transIndex = 0x8000;
  284. #endif
  285.         (**colors).ctSeed = GetCTSeed();
  286.         (**colors).ctTable[0].rgb = whiteRGB; /*first entry is white*/
  287.         (**colors).ctTable[1].rgb = blackRGB; /*second entry is black*/
  288.         /* Now play back the picture to get the colors.  The dstRect doesn't
  289.             matter since our bottlenecks will never actually draw. We use global
  290.             variables (gColorError and gColorTable) to communicate with the
  291.             bottlenecks. */
  292. #ifdef applec
  293.         (*(qd.thePort)).grafProcs = (QDProcs *) &bottlenecks;
  294. #else
  295.         (*thePort).grafProcs = (QDProcs *) &bottlenecks;
  296. #endif
  297.         gColorError = noErr;
  298.         gColorTable = colors;
  299.         DrawPicture(fromPicture, &((**fromPicture).picFrame));
  300. #ifdef applec
  301.         (*(qd.thePort)).grafProcs = 0L;
  302. #else
  303.         (*thePort).grafProcs = 0L;
  304. #endif
  305.         *depthPtr = maxPixDepth;
  306.         *directFlagPtr = foundDirect;
  307.  
  308.         /* Fail if error occurred while within the color bottlenecks. */
  309.         if (gColorError != noErr) {
  310.             DisposeHandle((Handle)colors);
  311.             colors = 0L;
  312.         }
  313.     }
  314.     return colors;
  315. }
  316.